package code.hkgolden.android.service;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;

import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import android.content.Context;
import code.hkgolden.android.data.Topic;

import com.google.inject.Inject;
import com.google.inject.Singleton;

@Singleton
public class DefaultContentService implements ContentService {

	private ObjectMapper mapper;

	@Inject
	private HttpService httpService;

	@Inject
	private CacheService cacheService;

	protected final Logger logger = LoggerFactory.getLogger(getClass());

	public DefaultContentService() {
		mapper = new ObjectMapper();
	}

	public Collection<Topic> topics(URL url) throws IOException {
		final String jsonData = httpService.getFromUrl(url);
		if (jsonData == null) {
			return null;
		}
		final JsonNode rootNode = mapper.readValue(jsonData, JsonNode.class);
		return mapper.readValue(rootNode.get("topic_list").traverse(),
				new TypeReference<ArrayList<Topic>>() {
				});
	}

	public Collection<Topic> topics(String type, int offset, int size)
			throws IOException {
		logger.debug("topics()");
		// final URL url = new URL("http://api.hkgolden.com/topics.aspx"
		// + "?returntype=json" + "&page=" + (offset / size)
		// + "&pagesize=" + size + "&type=" + type);
		final URL url = new URL("http://api.hkgolden.com/topics.aspx"
				+ "?returntype=json" + "&page=" + 1 + "&pagesize=" + 30
				+ "&type=" + type);
		String key = url.getPath() + "?" + url.getQuery();
		logger.debug("cache.key = {}", key);
		Collection<Topic> topics = (Collection<Topic>) cacheService.get(key);
		logger.trace("topics = {}", topics);
		if (topics != null) {
			return topics;
		}
		topics = this.topics(url);
		logger.trace("topics = {}", topics);
		cacheService.put(key, topics);
		return topics;
	}

	@Override
	public Topic replies(URL url) throws Exception {
		final String jsonData = httpService.getFromUrl(url);
		if (jsonData == null) {
			return null;
		}
		return mapper.readValue(jsonData, new TypeReference<Topic>() {
		});
	}

	@Override
	public Topic replies(int id, int offset, int size) throws Exception {
		// final int end = page * 50;
		// final int start = end - 49;
		final URL url = new URL("http://api.hkgolden.com/view.aspx"
				+ "?returntype=json" + "&message=" + id + "&start=" + offset
				+ "&end=" + (offset + size));
		String key = url.getPath() + "?" + url.getQuery();
		logger.trace("cache.key = {}", key);
		Topic topic = (Topic) cacheService.get(key);
		if (topic != null) {
			return topic;
		}
		topic = this.replies(url);
		cacheService.put(key, topic);
		return topic;
	}

	private Map<String, String> channelMap;

	@Inject
	ChannelParser channelParser;

	@Override
	public Map<String, String> channels(Context context) throws IOException {
		if (channelMap != null) {
			return channelMap;
		}
		InputStream inputStream = context.getAssets().open("channels.xml");
		channelMap = channelParser.channels(inputStream);
		return channelMap;
	}
}
